You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

36 lines
1.5 KiB

import fs from "node:fs";
import path from "node:path";
import { sendStream, setHeader } from "h3";
import { getExportTaskForUser } from "#server/service/export/jobs";
export default defineWrappedResponseHandler(async (event) => {
const user = await event.context.auth.requireUser();
const idRaw = getRouterParam(event, "id");
const taskId = Number(idRaw);
if (!Number.isInteger(taskId) || taskId < 1) {
throw createError({ statusCode: 400, statusMessage: "无效的任务 id" });
}
const task = await getExportTaskForUser(taskId, user.id);
if (!task) {
throw createError({ statusCode: 404, statusMessage: "导出任务不存在" });
}
if (task.status !== "succeeded") {
throw createError({ statusCode: 409, statusMessage: "导出任务尚未完成" });
}
if (!task.expiresAt || task.expiresAt.getTime() <= Date.now()) {
throw createError({ statusCode: 410, statusMessage: "导出结果已过期" });
}
if (!task.outputDir || !task.outputName) {
throw createError({ statusCode: 500, statusMessage: "导出结果缺失" });
}
const manifestPath = path.resolve(task.outputDir, "manifest.json");
if (!fs.existsSync(manifestPath)) {
throw createError({ statusCode: 404, statusMessage: "导出文件不存在" });
}
setHeader(event, "Content-Type", "application/json; charset=utf-8");
setHeader(event, "Content-Disposition", `attachment; filename="${task.outputName}-manifest.json"`);
return sendStream(event, fs.createReadStream(manifestPath));
});